// Copyright (C) ZHENG Zhong <heavyzheng nospam-at gmail D0T com>
//
// $Id: log_level.hpp 223 2008-09-08 09:37:19Z heavyzheng $
//

#ifndef ZZHENG_LOGGING_LOG_LEVEL_HPP_20080630__
#define ZZHENG_LOGGING_LOG_LEVEL_HPP_20080630__

#include <zzheng/logging/config.hpp>
#include <string>

namespace zzheng {
namespace logging {

    //! The log level number constants.
    enum log_level_constants {
        trace_level_number     = 0,                 //!< The trace level number.
        debug_level_number     = 100,               //!< The debug level number.
        info_level_number      = 200,               //!< The info level number.
        warn_level_number      = 300,               //!< The warn level number.
        error_level_number     = 400,               //!< The error level number.
        fatal_level_number     = 500,               //!< The fatal level number.
        off_level_number       = 1000,              //!< The off (highest) level number.
        undefined_level_number = 10000,             //!< The undefined level number.
        default_level_number   = warn_level_number, //!< The default level number.
    }; // enum level_constants

    ////////////////////////////////////////////////////////////////////////////////////////////////

    class log_level {

    public:

        //! Default constructor to construct a default log level.
        explicit log_level(): number_(default_level_number) {
            // Do nothing.
        }

        //! Constructs a log level object using the specified level number.
        //! \param number  the level number.
        explicit log_level(int number): number_(number) {
            // Do nothing.
        }

        // Use auto-generated copy constructor.
        // Use auto-generated copy assignment.
        // Use auto-generated destructor.

        bool operator==(const log_level& rhs) const {
            return (number_ == rhs.number_);
        }

        bool operator<(const log_level& rhs) const {
            return (number_ < rhs.number_);
        }

        bool operator!=(const log_level& rhs) const {
            return !operator==(rhs);
        }

        bool operator>(const log_level& rhs) const {
            return (!operator==(rhs) && !operator<(rhs));
        }

        bool operator<=(const log_level& rhs) const {
            return (operator==(rhs) || operator<(rhs));
        }

        bool operator>=(const log_level& rhs) const {
            return !operator<(rhs);
        }

        //! Returns the integer level number.
        //! \return the integer level number.
        int number() const {
            return number_;
        }

        //! Returns a string representation of this log level.
        //! \return a string representation of this log level.
        std::string str() const {
            std::string tmp;
            if (number_ <= trace_level_number) {
                tmp = "TRACE";
            } else if (number_ <= debug_level_number) {
                tmp = "DEBUG";
            } else if (number_ <= info_level_number) {
                tmp = "INFO";
            } else if (number_ <= warn_level_number) {
                tmp = "WARN";
            } else if (number_ <= error_level_number) {
                tmp = "ERROR";
            } else if (number_ <= fatal_level_number) {
                tmp = "FATAL";
            } else if (number_ <= off_level_number) {
                tmp = "OFF";
            } else {
                tmp = "???"; // undefined.
            }
            return tmp;
        }

    private:

        int number_; //!< The log level number.

    }; // class log_level

    ////////////////////////////////////////////////////////////////////////////////////////////////

    inline
    log_level undefined_level() {
        return log_level(undefined_level_number);
    }

    inline
    log_level trace_level() {
        return log_level(trace_level_number);
    }

    inline
    log_level debug_level() {
        return log_level(debug_level_number);
    }

    inline
    log_level info_level() {
        return log_level(info_level_number);
    }

    inline
    log_level warn_level() {
        return log_level(warn_level_number);
    }

    inline
    log_level error_level() {
        return log_level(error_level_number);
    }

    inline
    log_level fatal_level() {
        return log_level(fatal_level_number);
    }

    inline
    log_level off_level() {
        return log_level(off_level_number);
    }

    inline
    log_level default_level() {
        return log_level(default_level_number);
    }

} // namespace zzheng::logging
} // namespace zzheng

#endif // ZZHENG_LOGGING_LOG_LEVEL_HPP_20080630__


